/**
 * 习题类
 * 管理一组算式对象，提供习题生成、答题、成绩计算等功能
 */
public class Exercise {
    // 存储算式对象的数组
    private AbstractCalculation[] calculations;
    // 习题总数
    private int totalCount;
    // 答对的数量
    private int correctCount;
    // 记录每个算式的答题状态（是否已答）
    private boolean[] answered;
    // 记录每个算式的答案是否正确
    private boolean[] isCorrect;
    
    /**
     * 构造函数
     * @param totalCount 习题总数
     */
    public Exercise(int totalCount) {
        if (totalCount <= 0) {
            throw new IllegalArgumentException("习题数量必须大于0");
        }
        
        this.totalCount = totalCount;
        this.calculations = new AbstractCalculation[totalCount];
        this.correctCount = 0;
        this.answered = new boolean[totalCount];
        this.isCorrect = new boolean[totalCount];
        
        // 初始化答题状态数组
        for (int i = 0; i < totalCount; i++) {
            answered[i] = false;
            isCorrect[i] = false;
        }
        
        // 默认生成混合习题（加法和减法）
        generateMixedExercises();
    }
    
    /**
     * 生成混合习题（加法和减法）
     * 这将替换现有的所有习题
     */
    public void generateMixedExercises() {
        for (int i = 0; i < totalCount; i++) {
            // 随机决定是加法还是减法
            if (Math.random() < 0.5) {
                calculations[i] = AdditionCalculation.createValidAddition();
            } else {
                calculations[i] = SubtractionCalculation.createValidSubtraction();
            }
            // 重置答题状态
            answered[i] = false;
            isCorrect[i] = false;
        }
        // 重置正确计数
        correctCount = 0;
    }
    
    /**
     * 生成指定数量的加法习题
     * @param count 加法习题数量
     */
    public void generateAdditionExercises(int count) {
        if (count <= 0 || count > totalCount) {
            throw new IllegalArgumentException("加法习题数量必须在1到" + totalCount + "之间");
        }
        
        // 生成指定数量的加法习题
        for (int i = 0; i < count; i++) {
            calculations[i] = AdditionCalculation.createValidAddition();
            // 重置答题状态
            answered[i] = false;
            isCorrect[i] = false;
        }
        
        // 剩余部分保持不变
        // 重置正确计数
        correctCount = 0;
    }
    
    /**
     * 生成指定数量的减法习题
     * @param count 减法习题数量
     */
    public void generateSubtractionExercises(int count) {
        if (count <= 0 || count > totalCount) {
            throw new IllegalArgumentException("减法习题数量必须在1到" + totalCount + "之间");
        }
        
        // 生成指定数量的减法习题
        for (int i = 0; i < count; i++) {
            calculations[i] = SubtractionCalculation.createValidSubtraction();
            // 重置答题状态
            answered[i] = false;
            isCorrect[i] = false;
        }
        
        // 剩余部分保持不变
        // 重置正确计数
        correctCount = 0;
    }
    
    /**
     * 回答指定索引的习题
     * @param index 习题索引（从0开始）
     * @param answer 用户提供的答案
     * @return 是否回答正确
     */
    public boolean answerQuestion(int index, int answer) {
        // 检查索引是否有效
        if (index < 0 || index >= totalCount) {
            throw new IndexOutOfBoundsException("索引超出范围: " + index);
        }
        
        // 获取对应的算式
        AbstractCalculation calc = calculations[index];
        // 验证答案
        boolean correct = calc.checkAnswer(answer);
        
        // 更新状态
        answered[index] = true;
        
        // 如果之前回答错误，现在回答正确，增加正确计数
        if (correct && !isCorrect[index]) {
            correctCount++;
        } 
        // 如果之前回答正确，现在回答错误，减少正确计数
        else if (!correct && isCorrect[index]) {
            correctCount--;
        }
        
        // 更新当前答案的正确性状态
        isCorrect[index] = correct;
        
        return correct;
    }
    
    /**
     * 获取指定索引的算式
     * @param index 算式索引（从0开始）
     * @return 算式对象
     */
    public AbstractCalculation getCalculation(int index) {
        // 检查索引是否有效
        if (index < 0 || index >= totalCount) {
            throw new IndexOutOfBoundsException("索引超出范围: " + index);
        }
        return calculations[index];
    }
    
    /**
     * 获取所有习题的字符串数组
     * @return 包含所有习题字符串的数组
     */
    public String[] getExerciseStrings() {
        String[] exerciseStrings = new String[totalCount];
        for (int i = 0; i < totalCount; i++) {
            exerciseStrings[i] = (i + 1) + ". " + calculations[i].getExpression() + " = ";
        }
        return exerciseStrings;
    }
    
    /**
     * 格式化打印所有习题
     * 每行显示5道题
     */
    public void printExercises() {
        final int COLUMNS = 5; // 每行显示5道题
        
        for (int i = 0; i < totalCount; i += COLUMNS) {
            StringBuilder line = new StringBuilder();
            
            // 构建一行的习题
            for (int j = 0; j < COLUMNS && i + j < totalCount; j++) {
                int index = i + j;
                // 格式化习题为 "(序号) 表达式 =  " 的形式
                String exercise = String.format("(%2d) %s =  ", 
                                              index + 1, 
                                              calculations[index].getExpression());
                line.append(exercise);
            }
            
            System.out.println(line.toString());
        }
    }
    
    /**
     * 打印练习结果
     */
    public void printResult() {
        System.out.println("\n===== 练习结果 =====");
        System.out.println("总题目数: " + totalCount);
        System.out.println("答对题目: " + correctCount);
        System.out.println("正确率: " + getAccuracy() + "%");
        
        // 可以添加更多详细的结果信息，如错题列表等
    }
    
    /**
     * 获取习题总数
     * @return 习题总数
     */
    public int getTotalCount() {
        return totalCount;
    }
    
    /**
     * 获取答对的数量
     * @return 答对的数量
     */
    public int getCorrectCount() {
        return correctCount;
    }
    
    /**
     * 获取正确率（百分比）
     * @return 正确率
     */
    public double getAccuracy() {
        if (totalCount == 0) {
            return 0.0;
        }
        return (double) correctCount / totalCount * 100;
    }
    
    /**
     * 检查是否所有习题都已回答
     * @return 是否所有习题都已回答
     */
    public boolean isAllAnswered() {
        for (boolean a : answered) {
            if (!a) {
                return false;
            }
        }
        return true;
    }
}